home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / BORLAND TURBO / DOCVIEW.PAK / ODLISTBX.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  5.0 KB  |  166 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // Copyright (c) 1993, 1995 by Borland International, All Rights Reserved
  4. //
  5. //   Implements class TODListBox
  6. //----------------------------------------------------------------------------
  7. #include <owl/pch.h>
  8. #include "odlistbx.h"
  9.  
  10. TODListBox::TODListBox(int id)
  11. :
  12.   TControl(0, id, 0, 0,0, 100,100),
  13.   BufTemp(0),
  14.   BufLen(0),
  15.   MaxWidth(0)
  16. {
  17.   Attr.Style &= ~(LBS_SORT | LBS_HASSTRINGS | LBS_MULTIPLESEL);
  18.   Attr.Style |= (LBS_NOTIFY | WS_VSCROLL | WS_HSCROLL | WS_BORDER | LBS_OWNERDRAWVARIABLE);
  19. }
  20.  
  21. char far *
  22. TODListBox::GetClassName()
  23. {
  24.   return "LISTBOX";
  25. }
  26.  
  27. void TODListBox::ItemRedraw(int index)   // force item to be redrawn
  28. {
  29.   TRect rect;
  30.   if (GetItemRect(index, rect) <= 0)
  31.     return;   // return 1 if OK, -1 if error
  32.   InvalidateRect(rect);
  33. }
  34.  
  35. void TODListBox::DrawItem(DRAWITEMSTRUCT far & dis)
  36. {
  37.   ODItemInfo item;
  38.   uint action = dis.itemAction;
  39.   item.Hdc = dis.hDC;
  40.   item.State = dis.itemState;
  41.   item.Data  = (void far*) dis.itemData;
  42.   item.Index = dis.itemID;
  43.   item.Bound.Set(dis.rcItem.left, dis.rcItem.top,
  44.                  dis.rcItem.right,dis.rcItem.bottom);
  45.  
  46.   if (item.Index < 0)
  47.     return; // ignore if empty listbox, no focus rect?
  48.   GetItemInfo(item);       // must fill in: Extent,Text,TextLen,Offset
  49.   if (action & ODA_DRAWENTIRE){
  50. //   // shift the item rect to account for horizontal scrolling
  51. //if (item.Bound.right > clientrect.right)
  52. //      item.Bound.left = -(item.Bound.right - clientrect.right);
  53.   if (item.Extent.cx > MaxWidth) {
  54.     SetHorizontalExtent(MaxWidth = item.Extent.cx);
  55.   }
  56.   DrawItemData(item);      
  57.   action = 0;  // redraw destoys previous focus and selection painting
  58.   if (item.State & ODS_SELECTED) action |= ODA_SELECT;
  59.   if (item.State & ODS_FOCUS)    action |= ODA_FOCUS;
  60.   }
  61.   if (action & ODA_SELECT) {
  62.     ChangeHilight(item);
  63.   }
  64.   if (action & ODA_FOCUS){
  65.    item.Bound.right = item.Extent.cx;  // focus drawn around entire item
  66.    ChangeFocus(item);
  67.   }
  68. }
  69.  
  70. void TODListBox::MeasureItem (MEASUREITEMSTRUCT far& mis)
  71. {
  72.   ODItemInfo item;
  73.   item.Hdc = ::GetDC(*this);
  74.   item.Data  = (void far*) mis.itemData;
  75.   item.Index = mis.itemID;
  76.   item.State = 0;
  77.   GetItemInfo(item);
  78.   mis.itemHeight = item.Extent.cy;
  79.   mis.itemWidth  = item.Extent.cx;
  80.   if (item.Extent.cx > MaxWidth) {
  81.      SetHorizontalExtent(MaxWidth = item.Extent.cx);
  82.   }
  83.   ::ReleaseDC(*this, item.Hdc);
  84. }
  85.  
  86. // The following methods are defaults for use with text string items only.
  87. // These must be overridden if for data items that are not standard text.
  88. // If the style LBS_HASSTRINGS is set, strings are stored within the list box.
  89. // Otherwise only the pointers are stored; data must be managed by the caller.
  90.  
  91. bool TODListBox::GetItemInfo(ODItemInfo& item) {
  92.   LPSTR str;
  93.   int len;
  94.   if (Attr.Style & LBS_HASSTRINGS) {   // strings stored in list box
  95.     len = GetStringLen(item.Index);
  96.     if (len == 0) {
  97.       str = 0;
  98.     } else {
  99.       if (len >= BufLen){  // check temporary buffer size
  100.         if (BufTemp) delete BufTemp;
  101.         BufTemp = new char[BufLen = len+1];
  102.       }
  103.       GetString(str = BufTemp, item.Index);
  104.     }
  105.   } else { // assume text pointer is allocated data stored in item data     
  106.     str = (char far*)item.Data;
  107.     len = str ? lstrlen(str) : 0;
  108.   }
  109.   item.TextLen = len;
  110.   item.Text = str;
  111.   if (!len) {
  112.     str = " ";     // must have text to measure
  113.     len++;
  114.   }
  115.   GetTextExtentPoint(item.Hdc, str, len, &item.Extent);
  116.   item.Extent.cx += 2; // room for focus rectangle
  117.   item.Extent.cy += 2; // room for focus rectangle
  118.   item.Offset.x = 1;   // room for focus rectangle, no indentation
  119.   item.Offset.y = 1;   // room for focus rectangle
  120.   return true;         // OK to draw
  121. }
  122.  
  123. void TODListBox::ChangeHilight(ODItemInfo& item)
  124. {
  125.   InvertRect(item.Hdc, &item.Bound);  // need to fix to do nicer!!
  126. }
  127.  
  128. void TODListBox::ChangeFocus(ODItemInfo& item)
  129. {
  130.   int brushtype = item.State & ODS_FOCUS ? LTGRAY_BRUSH
  131.                 :(item.State & ODS_SELECTED ? BLACK_BRUSH : WHITE_BRUSH);
  132.   FrameRect(item.Hdc, &item.Bound, (HBRUSH)GetStockObject(brushtype));
  133. }
  134.  
  135. void TODListBox::DrawItemData(ODItemInfo& item)
  136. {
  137. //HFONT oldfont = SelectObject(item.Hdc, StdFont);  // need member HFONT StdFont
  138.   ExtTextOut(item.Hdc, 
  139.          item.Bound.left + item.Offset.x,
  140.          item.Bound.top  + item.Offset.y,
  141.          ETO_CLIPPED | ETO_OPAQUE, 
  142.          &item.Bound,
  143.          item.Text, item.TextLen,
  144.          (LPINT) NULL); /* default char spacing */ 
  145. //SelectObject(item.Hdc, oldfont);
  146. }
  147.  
  148. IMPLEMENT_STREAMABLE1(TODListBox, TControl);
  149.  
  150. void*
  151. TODListBox::Streamer::Read(ipstream& is, uint32 /*version*/) const
  152. {
  153.   ReadBaseObject((TControl*)GetObject(), is);
  154.   is >> GetObject()->MaxWidth;
  155.   GetObject()->BufTemp = 0;
  156.   GetObject()->BufLen  = 0;
  157.   return GetObject();
  158. }
  159.  
  160. void
  161. TODListBox::Streamer::Write(opstream& os) const
  162. {
  163.   WriteBaseObject((TControl*)GetObject(), os);
  164.   os << GetObject()->MaxWidth;
  165. }
  166.